package com.link.base.core.basic.interceptors.mybatis.system;

import com.alibaba.fastjson.JSON;
import com.link.base.user.model.CoreUser;
import com.link.base.base.trackchild.model.Trackchild;
import com.link.base.base.trackchild.service.TrackchildService;
import com.link.base.base.trackhead.model.Trackhead;
import com.link.base.base.trackhead.service.TrackheadService;
import com.link.core.cllog.LCLogger;
import com.link.core.basic.model.BasicModel;
import com.link.core.basic.query.Filter;
import com.link.core.basic.query.QueryParams;
import com.link.core.util.RedisUtil;
import com.link.core.util.UserUtil;
import com.link.core.util.redisclient.LinkRedisClient;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author: qinxuegang
 * @Description:
 * @Date: 2018/11/29 13:51
 */
@Component
public class InterceptorUtils {
    private static final Logger logger = LogManager.getLogger(InterceptorUtils.class);
    @Resource
    private TrackheadService trackheadService;
    @Resource
    private TrackchildService trackchildService;

    /**
     * @Author: qinxuegang
     * @Description: 获取审计追踪头配置信息
     * @Date: 2018/11/26 11:54
     */
    public List<Trackhead> getHeadList(Set<String> listTableName, String type) {
        Trackhead trackhead = new Trackhead();
        QueryParams queryParams = new QueryParams();
        queryParams.setPageFlag(false);
        queryParams.addFilter(new Filter("trackCode", Filter.OP_IN, new ArrayList<>(listTableName)));
        queryParams.addFilter(new Filter(type, "Y"));
        Trackhead example = (Trackhead) BasicModel.transformClass(Trackhead.class, queryParams);
        List<Trackhead> list = new ArrayList<>();
        try {
            list = trackheadService.queryByExamplePage(example);
        } catch (Exception e) {
            LCLogger.withException(e);
        }
        return list;
    }


    /**
     * @Author: qinxuegang
     * @Description: 获取审计追踪配置信息
     * @Date: 2018/11/26 11:54
     */
    public Map<String, Object> getHeadAndChild(Set<String> listTableName, String type) {

        LinkRedisClient jedis = RedisUtil.getJedis();
        Map<String, Object> result = new HashMap<>();
        String[] tables = new String[listTableName.size()];
        int i = 0;
        for (String str : listTableName) {
            tables[i] = str.toLowerCase();
            i++;
        }
        CoreUser user = UserUtil.getUser();
        if (jedis == null || user == null) {
            result.put("trackheads", null);
            result.put("trackchilds", null);
            return result;
        }
        List<String> rsmap = jedis.hmget("TRACK_CONFIG_LIST_" + user.getCorpid(), tables);
        List<Trackhead> trackheads = new ArrayList<>();
        Map<String, List<Trackchild>> map = new HashMap<>();
        for (String str : rsmap) {
            List<Trackchild> listChild = readListValue(rsmap.get(0), Trackchild.class);
            if (listChild == null || listChild.size() <= 0) {
                break;
            }
            Trackchild trackchild = listChild.get(0);
            Trackhead trackhead = new Trackhead();
            boolean flag = ("trackUpd".equals(type) && "y".equals(trackchild.getTrackUpd()))
                    || ("trackDel".equals(type) && "y".equals(trackchild.getTrackDel()))
                    || ("trackNew".equals(type) && "y".equals(trackchild.getTrackNew()));
            if (flag) {
                //更新操作
                trackhead.setTrackCode(listChild.get(0).getTrackCode());
                trackhead.setTrackName(listChild.get(0).getTrackName());
                trackhead.setTrackDel(listChild.get(0).getTrackDel());
                trackhead.setTrackNew(listChild.get(0).getTrackNew());
                trackhead.setTrackUpd(listChild.get(0).getTrackUpd());
                trackheads.add(trackhead);
                map.put(listChild.get(0).getTrackCode(), listChild);
                break;
            }
        }
        logger.info(trackheads);
        result.put("trackheads", trackheads);
        result.put("trackchilds", map);
        return result;
    }


    public static <T> List<T> readListValue(String json, Class<T> tClazz) {
        return JSON.parseArray(json, tClazz);
    }

    /**
     * @Author: qinxuegang
     * @Description: 获取审计追踪字段配置信息
     * @Date: 2018/11/26 11:54
     */
    public List<Trackchild> getChildList(String headId) {
        Trackchild trackchild = new Trackchild();
        QueryParams queryParamsChild = new QueryParams();
        queryParamsChild.setPageFlag(false);
        queryParamsChild.addFilter(new Filter("headId", headId));
        queryParamsChild.addFilter(new Filter("isEffective", "Y"));
        Trackchild child = (Trackchild) BasicModel.transformClass(Trackchild.class, queryParamsChild);
        List<Trackchild> listChild = new ArrayList<>();
        try {
            listChild = trackchildService.queryByExamplePage(child);
        } catch (Exception e) {
            LCLogger.withException(e);
        }
        return listChild;
    }

    /**
     * @Author: qinxuegang
     * @Description:把第一个字母变为大写
     * @Date: 2018/11/1 11:54
     */
    public static String getoUpperCaseChar(String str) {
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }


    /**
     *      * 正则表达式匹配两个指定字符串中间的内容
     *      * @param soap
     *      * @return
     *     
     */
    public static String getSubUtil(String soap, String rgex) {
        List<String> list = new ArrayList<String>();
        Pattern pattern = Pattern.compile(rgex);
        Matcher m = pattern.matcher(soap);
        //m.replaceAll("").trim();
        while (m.find()) {
            int i = 0;
            //m.replaceAll("");
            //m.appendReplacement(m.group(i), "");
            soap = soap.replace(m.group(i), "");
            i++;
        }
        return soap;
    }

    /**
     *      * 正则表达式匹配两个指定字符串中间的内容
     *      * @param soap
     *      * @return
     *     
     */
    public static List<String> getInsertUtil(String sql, String rgex) {
        List<String> list = new ArrayList<String>();
        Pattern pattern = Pattern.compile(rgex);
        Matcher m = pattern.matcher(sql);
        while (m.find()) {
            int i = 0;
            list.add(m.group(i));
            sql = sql.replace(m.group(i), "insertFunction");
            i++;
        }
        list.add(sql);
        return list;
    }

    /**
     * 利用正则表达式判断字符串是否是数字
     *
     * @param orginal
     * @return
     */
    public static boolean isDecimal(String orginal) {
        return isMatch("[-+]{0,1}\\d+\\.\\d*|[-+]{0,1}\\d*\\.\\d+", orginal);
    }

    /**
     * 使用java正则表达式去掉多余的.与0
     *
     * @param s
     * @return
     */
    public static String subZeroAndDot(String s) {
        if (s.indexOf(".") > 0) {
            s = s.replaceAll("0+?$", "");//去掉多余的0
            s = s.replaceAll("[.]$", "");//如最后一位是.则去掉
        }
        return s;
    }

    /**
     * 正则表达式匹配
     *
     * @param regex   正则规则
     * @param orginal 匹配内容
     * @return
     */
    private static boolean isMatch(String regex, String orginal) {
        if (orginal == null || orginal.trim().equals("")) {
            return false;
        }
        Pattern pattern = Pattern.compile(regex);
        Matcher isNum = pattern.matcher(orginal);
        return isNum.matches();
    }


    /**
     * @param model        对象
     * @param propertyName 属性名
     * @return
     * @description:根据属性名调用Get方法
     * @author: qinxuegang
     */
    public static Object dynamicGet(BasicModel model, List<Field> fields, String propertyName) {
        try {
            for (Field field : fields) {
                if (field.getName().equalsIgnoreCase(propertyName)) {
                    field.setAccessible(true);
                    Object object = field.get(model);
                    return object;
                }
            }
        } catch (Exception e) {
            LCLogger.withException(e);
        }
        return null;
    }

    /**
     * @param clazz 对象
     * @return
     * @description:获取属性字段
     * @author: qinxuegang
     */
    public static List<Field> getFieldList(Class<?> clazz) {
        if (null == clazz) {
            return null;
        }
        List<Field> fieldList = new LinkedList<Field>();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            /** 过滤静态属性**/
            if (Modifier.isStatic(field.getModifiers())) {
                continue;
            }
            /** 过滤transient 关键字修饰的属性**/
            if (Modifier.isTransient(field.getModifiers())) {
                continue;
            }
            fieldList.add(field);
        }
        /** 处理父类字段**/
        Class<?> superClass = clazz.getSuperclass();
        if (superClass.equals(Object.class)) {
            return fieldList;
        }
        fieldList.addAll(getFieldList(superClass));
        return fieldList;
    }

}
